package com.shensi.adminCollect.service.markert.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shensi.adminCollect.common.constant.Constants;
import com.shensi.adminCollect.common.constant.UserConstants;
import com.shensi.common.core.domain.AjaxResult;
import com.shensi.adminCollect.common.enums.PayTypeEnum;
import com.shensi.adminCollect.common.exception.CustomException;
import com.shensi.adminCollect.common.utils.EnumsContainer;
import com.shensi.adminCollect.common.utils.LocalDateUtils;
import com.shensi.adminCollect.common.utils.poi.ExcelUtil;
import com.shensi.adminCollect.service.coupon.ICouponUserService;
import com.shensi.adminCollect.domain.markert.SaleActivity;
import com.shensi.adminCollect.domain.markert.SaleActivityOrder;
import com.shensi.adminCollect.domain.markert.req.SaleActivityOrderQueryReq;
import com.shensi.adminCollect.domain.markert.vo.SaleActivityOrderExportVO;
import com.shensi.adminCollect.domain.markert.vo.SaleActivityOrderSumVO;
import com.shensi.adminCollect.enums.markert.OrderStatus;
import com.shensi.adminCollect.enums.markert.ShipmentStatus;
import com.shensi.adminCollect.mapper.markert.SaleActivityOrderMapper;
import com.shensi.adminCollect.service.markert.ISaleActivityOrderService;
import com.shensi.adminCollect.service.markert.ISaleActivityService;
import com.shensi.adminCollect.util.markert.PrintUtil;
import com.shensi.adminCollect.domain.station.PayOrder;
import com.shensi.adminCollect.domain.station.PayWay;
import com.shensi.adminCollect.service.station.IPayOrderService;
import com.shensi.adminCollect.service.station.IPayWayService;
import com.shensi.adminCollect.domain.system.SysRespon;
import com.shensi.adminCollect.utils.system.MyLambadaUpdateWrapper;
import com.shensi.common.core.domain.entity.SysUser;
import com.shensi.common.core.domain.model.LoginUser;
import com.shensi.common.core.utils.SecurityUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @date 2023/12/21
 */


@Service
public class SaleActivityOrderServiceImpl extends ServiceImpl<SaleActivityOrderMapper, SaleActivityOrder> implements ISaleActivityOrderService {

    private static final Logger log = LoggerFactory.getLogger(SaleActivityOrderServiceImpl.class);

    @Autowired
    private IPayOrderService payOrderService;
    @Autowired
    private ISaleActivityService saleActivityService;
    @Autowired
    private IPayWayService payWayService;
    @Autowired
    private ICouponUserService couponUserService;
    @Autowired
    private PrintUtil printUtil;

    @Override
    public List<SaleActivityOrder> queryList(SaleActivityOrderQueryReq queryReq) {
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser sysUser = user.getUser();
        if (StringUtils.equals(UserConstants.LEVEL_TWO,sysUser.getUserLevel())) {
            // 油企
            queryReq.setEnterpriseId(sysUser.getEnterpriseId());
        }else if(StringUtils.equals(UserConstants.LEVEL_THREE,sysUser.getUserLevel())){
            // 油站
            queryReq.setStationId(sysUser.getStationId());
            queryReq.setEnterpriseId(sysUser.getEnterpriseId());
        }
        LambdaQueryWrapper<SaleActivityOrder> qw = Wrappers.lambdaQuery(queryReq);
        if (CollectionUtils.isNotEmpty(queryReq.getPayTypeList())) {
            queryReq.setPayType(null);
            qw.in(SaleActivityOrder::getPayType,queryReq.getPayTypeList());
        }
        if (queryReq.getBeginTime() != null && queryReq.getEndTime() != null) {
            qw.gt(SaleActivityOrder::getPayTime,queryReq.getBeginTime())
                    .lt(SaleActivityOrder::getPayTime,queryReq.getEndTime());
        }
        qw.orderByDesc(SaleActivityOrder::getId);
        return list(qw);
    }

    @Override
    @Transactional
    public void refund(Long orderId){
        SaleActivityOrder order = getById(orderId);
        if (order == null) {
            return;
        }
        if (!Objects.equals(order.getOrderStatus(), OrderStatus.PAID.getCode())) {
            throw new CustomException("该订单无法退款");
        }
        if (order.getPayWayId() == null) {
            throw new CustomException("支付渠道未找到");
        }
        PayWay payWay = payWayService.selectPayWayById(order.getPayWayId());
        if (payWay == null) {
            throw new CustomException("支付渠道未找到");
        }
        couponUserService.recoveryUserCoupon(order.getMobilePhone(), 8,order.getId(),Constants.COUPON_USER_BIZ_TYPE_SALE_ACTIVITY,true);
        doRefund(order, com.shensi.adminCollect.common.utils.StringUtils.generateOrdNo(),payWay);
    }

    @Override
    public SaleActivityOrderSumVO saleActivityOrderSum(SaleActivityOrderQueryReq queryReq) {
        LoginUser user = SecurityUtils.getLoginUser();
        SysUser sysUser = user.getUser();
        if (StringUtils.equals(UserConstants.LEVEL_TWO,sysUser.getUserLevel())) {
            // 油企
            queryReq.setEnterpriseId(sysUser.getEnterpriseId());
        }else if(StringUtils.equals(UserConstants.LEVEL_THREE,sysUser.getUserLevel())){
            // 油站
            queryReq.setStationId(sysUser.getStationId());
            queryReq.setEnterpriseId(sysUser.getEnterpriseId());
        }
        queryReq.setOrderStatus(OrderStatus.PAID.getCode());
//        LambdaQueryWrapper<SaleActivityOrder> qw = Wrappers.lambdaQuery(queryReq);
//        if (queryReq.getBeginTime() != null && queryReq.getEndTime() != null) {
//            qw.gt(SaleActivityOrder::getCreateTime,queryReq.getBeginTime())
//                    .lt(SaleActivityOrder::getCreateTime,queryReq.getEndTime());
//        }
        SaleActivityOrderSumVO orderSumVO = baseMapper.sumSaleActivityOrder(queryReq);
        if (orderSumVO.getAmt() == null) {
            orderSumVO.setAmt(BigDecimal.ZERO);
        }
        return orderSumVO;
    }

    @Override
    public AjaxResult export(SaleActivityOrderQueryReq queryReq) {
        List<SaleActivityOrder> saleActivityOrders = queryList(queryReq);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(LocalDateUtils.DATETIME_14_FORMAT);
        List<SaleActivityOrderExportVO> exportVOS = saleActivityOrders.stream().map(order -> {
            SaleActivityOrderExportVO exportVO = new SaleActivityOrderExportVO();
            BeanUtils.copyProperties(order, exportVO);
            if (order.getPayTime() != null) {
                exportVO.setPayTime(formatter.format(order.getPayTime()));
            }
            exportVO.setPayType(PayTypeEnum.getByType(exportVO.getPayType(),PayTypeEnum.wx).getDes());
            exportVO.setOrderStatus(EnumsContainer.getEnumByKey(OrderStatus.class,order.getOrderStatus(),OrderStatus.NOT_PAY).getDesc());
            exportVO.setShipmentStatus(EnumsContainer.getEnumByKey(ShipmentStatus.class,order.getShipmentStatus(),ShipmentStatus.NOT_SHIP).getDesc());
            return exportVO;
        }).collect(Collectors.toList());
        ExcelUtil<SaleActivityOrderExportVO> excelUtil = new ExcelUtil<>(SaleActivityOrderExportVO.class);
        return excelUtil.exportExcel(exportVOS, "order");
    }

    private void doRefund(SaleActivityOrder order,String refundOrderNo, PayWay payWay){
        SysRespon sysRespon;
        String thirdOrderNo= null;
        String thirdPayNo = null;
        String payType = payWay.getPayType();
        switch (payType){
            case "1":  //随行付
                sysRespon = sxfRefund(order,refundOrderNo, payWay);
                if (sysRespon != null) {
                    if (sysRespon.getData() != null) {
                        HashMap<String, Object> data = (HashMap<String, Object>) sysRespon.getData();
                        thirdOrderNo = (String) data.get("uuid");
                    }
                    String code = sysRespon.getResponCode();
                    if (com.shensi.adminCollect.common.utils.StringUtils.equalsAny(code,"0000","2002")) {
                        callBackForRefundSuccess(order,refundOrderNo, LocalDateTime.now());
                    }else {
                        sysRespon = null;
                    }
                }
                break;
            case "5":  // 云化支付
                sysRespon = yunhuaRefund(order,refundOrderNo, payWay);
                if (sysRespon != null) {
                    if (sysRespon.getData() != null) {
                        JSONObject data = (JSONObject) sysRespon.getData();
                        thirdOrderNo = data.getString("refundTransInfoNo");
                        thirdPayNo = data.getString("refundTransPayNo");
                    }
                    if (com.shensi.adminCollect.common.utils.StringUtils.equals("0000",sysRespon.getResponCode())) {
                        callBackForRefundSuccess(order,refundOrderNo,LocalDateTime.now());
                    }else{
                        sysRespon = null;
                    }
                }
                break;
            default:
                throw new CustomException("不支持的支付渠道");
        }
        if (sysRespon == null) {
            //callBackForRefundFail(refundRecord,thirdOrderNo,thirdPayNo);
            log.error("退款失败");
            throw new CustomException("退款失败");
        }
    }

    private SysRespon sxfRefund(SaleActivityOrder order,String refundOrderNo, PayWay payWay){
        try {
            return payOrderService.sendSxfRefundOrder(order.getAmt(), refundOrderNo, order.getOrderNo(), payWay.getMno());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private SysRespon yunhuaRefund(SaleActivityOrder order,String refundOrderNo, PayWay payWay){
        try {
            PayOrder payOrder = new PayOrder();
            payOrder.setAmt(order.getAmt());
            payOrder.setReceivedAmt(order.getAmt());
            payOrder.setOrderNo(order.getOrderNo());
            payOrder.setMerchantsNumber(order.getTransNo());
            payOrder.setTransactionId(order.getPayNo());
            payOrder.setPayWayId(payWay.getPayWayId());
            payOrder.setStationId(order.getStationId());
            payOrder.setPayDate(LocalDateUtils.localDateTimeToDate(order.getPayTime()));
            return payOrderService.yunHuaRefundV2(refundOrderNo,payOrder, payWay);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private void callBackForRefundSuccess(SaleActivityOrder order,String refundOrderNo, LocalDateTime refundTime){
        log.info("退款成功回调，orderNo:[{}]，refundOrderNo:{}",order.getOrderNo(),refundOrderNo);
        SaleActivityOrder update = new SaleActivityOrder();
        update.setId(order.getId());
        update.setOrderStatus(OrderStatus.REFUND.getCode());
        update.setRefundTime(refundTime);
        if (Objects.equals(order.getShipmentStatus(), ShipmentStatus.SHIPPED.getCode())) {
            update.setShipmentStatus(ShipmentStatus.RECOVERED.getCode());
        }
        this.updateById(update);
        MyLambadaUpdateWrapper<SaleActivity> uw = new MyLambadaUpdateWrapper<>();
        uw.incrementSet(SaleActivity::getStock,order.getPurchaseNum()).eq(SaleActivity::getId,order.getSaleActivityId());
        saleActivityService.update(uw);
        log.info("充值退款成功回调-成功，orderNo:[{}]，refundOrderNo:{}",order.getOrderNo(),refundOrderNo);
        //退款打印小票
        order.setRefundTime(refundTime);
        printUtil.printRefundSaleOrder(order);
    }

}
